﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project.Co_DataTransformationPrototype.Data
{
    public sealed class DatabaseSettings
    {
        // Declarations
        private static DatabaseSettings instance;
        private string connectionString = string.Empty;
        private const string resourceAppPathString = @".\Resources\App.config";
        private const string metadataScriptFile = "MetadataScript.sql";
        internal const string resourceMetadataScriptPathString = @".\Resources\" + metadataScriptFile;
        internal const string SHEMA_NAME = "dbo";
        internal const string STAGING_SCHEMA_NAME = "dms";
        
        #region Private Constructor & GetInstance method
        private DatabaseSettings()
        { 
        }

        public static DatabaseSettings GetInstance()
        {
            if (instance == null)
                instance = new DatabaseSettings();

            return instance;
        }
        #endregion

        /// <summary>
        /// Getter for connection string
        /// </summary>
        public string ConnectionString
        {
            get { return connectionString; }
        }

        /// <summary>
        /// Builds the connection string based on the provided input
        /// </summary>
        /// <param name="sqlServerName"></param>
        /// <param name="sqlDataBaseName"></param>
        /// <param name="blnUsesIntegratedSecurity"></param>
        /// <param name="strUsername"></param>
        /// <param name="strPassword"></param>
        public void ConnectionStringBuilder(string sqlServerName, string sqlDataBaseName, bool blnUsesIntegratedSecurity, string strUsername = "", string strPassword = "")
        {
            if (!string.IsNullOrEmpty(sqlServerName) && !string.IsNullOrEmpty(sqlDataBaseName))
            {
                connectionString = string.Format("Data source={0}; Database={1}; ", sqlServerName, sqlDataBaseName);

                if (blnUsesIntegratedSecurity)
                    connectionString += "Trusted_Connection=yes;";
                else
                    connectionString += string.Format("User ID={0}; Password={1};", strUsername, strPassword);
            }
        }

        /// <summary>
        /// Persists the provided connection settings to an configuration file and refreshes the configuration manager
        /// </summary>
        /// <param name="SqlServerName"></param>
        /// <param name="SqlServerDatabase"></param>
        /// <param name="SqlServerUserName"></param>
        /// <param name="SqlServerUsesIntegratedSec"></param>
        public void SaveDBConnectionSettings(string SqlServerName, string SqlServerDatabase, string SqlServerUserName, bool SqlServerUsesIntegratedSec)
        {
            persistDBConnectionSettings("SQLDBHostName", SqlServerName);
            persistDBConnectionSettings("SQLDBName", SqlServerDatabase);
            persistDBConnectionSettings("SQLDBUserName", SqlServerUserName);
            persistDBConnectionSettings("SQLDBIntegratedSecurityEnabled", SqlServerUsesIntegratedSec.ToString());
        }

        private void persistDBConnectionSettings(string keyName, string keyValue)
        {
            //  AppDomain.CurrentDomain.SetupInformation.ConfigurationFile 
            // This will get the app.config file path from Current application Domain
            System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
            try
            {
                // Load XML Document
                XmlDoc.Load(resourceAppPathString);
                // Navigate Each XML Element of app.Config file
                foreach (System.Xml.XmlElement xElement in XmlDoc.DocumentElement)
                {
                    if (xElement.Name == "appSettings")
                    {
                        // Loop each node of appSettings Element 
                        // xNode.Attributes(0).Value , Mean First Attributes of Node , 
                        // KeyName Portion
                        // xNode.Attributes(1).Value , Mean Second Attributes of Node,
                        // KeyValue Portion
                        foreach (System.Xml.XmlNode xNode in xElement.ChildNodes)
                        {
                            if (xNode.Attributes[0].Value == keyName)
                                xNode.Attributes[1].Value = keyValue;
                        }
                    }
                }
                // Save app.config file
                XmlDoc.Save(resourceAppPathString);
            }
            finally
            {
                XmlDoc = null;
            }
        }
    }

}
